package model

import (
	"gin-blog/utils/msg"
	"github.com/jinzhu/gorm"
)

// Article 文章
type Article struct {
	gorm.Model
	Title   string `gorm:"type:varchar(20);not null;comment:文章标题" json:"title"`  // 文章标题
	Author  string `gorm:"type:varchar(20);not null;comment:文章作者" json:"author"` // 文章作者
	Cid     int    `gorm:"type:int;not null;comment:指向Category的id" json:"cid"`   // 指向Category的id
	Desc    string `gorm:"type:varchar(200);comment:文章描述" json:"desc"`           // 文章描述
	Context string `gorm:"type:longtext;comment:文章主体" json:"context"`            // 文章主体
	Img     string `gorm:"type:varchar(100);comment:文章图片" json:"img"`            // 文章图片
	// 指定逻辑外键，使用物理外键会导致数据库性能变差
	Category Category `gorm:"foreignKey:Cid;comment:分类;"` // 分类
}

// AddArticle 添加文章
func AddArticle(Article *Article) int {
	// 插入数据库
	err := db.Create(&Article).Error
	if err != nil {
		return msg.ERROR_ARTICLE_ADD
	}
	return msg.SUCCESS
}

// GetArticleInfo 根据id查询文章
func GetArticleInfo(id int) (Article, int) {
	var article Article
	err := db.Preload("Category").Where("id = ?", id).First(&article).Error
	// ErrRecordNotFound：没有记录
	if err != nil {
		return article, msg.ERROR_ARTICLE_NOT_EXIST
	}
	return article, msg.SUCCESS
}

// GetArticleByTitle 根据文章标题查询文章
func GetArticleByTitle(title string) (articles []Article, count int) {
	err := db.Where("title like %?%", title).Find(&articles).Count(&count).Error
	// ErrRecordNotFound：没有记录
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, 0
	}
	return articles, count
}

// GetArticleByCategory 根据文章分类查询文章
func GetArticleByCategory(cid int, pageSize int, pageNum int) (cateArtList []Article, count int) {
	err := db.Preload("Category").Limit(pageSize).Offset((pageNum-1)*pageSize).Where("cid = ?", cid).Find(&cateArtList).Count(&count).Error
	// ErrRecordNotFound：没有记录
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, 0
	}
	// 使用了预加载Preload，会导致Count查找出来的数量翻倍
	return cateArtList, count
}

// GetArticles 查询文章列表
func GetArticles(pageSize int, pageNum int) (articles []Article, count int) {
	// Preload是预加载
	err := db.Preload("Category").Limit(pageSize).Offset((pageNum - 1) * pageSize).Find(&articles).Count(&count).Error
	// ErrRecordNotFound：没有记录
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, 0
	}
	return articles, count
}

// DeleteArticle 删除文章
func DeleteArticle(id int) int {
	err := db.Where("id = ?", id).Delete(&Article{}).Error
	if err != nil {
		return msg.ERROR_ARTICLE_DELETE
	}
	return msg.SUCCESS
}

// EditArticle 修改文章，修改密码忽略，在别的地方实现
func EditArticle(article *Article, id int) int {
	// 可以直接传user进去，也可以传map进去，都会将有改变的值进行更新
	// 区别是传结构体不会更新零值，map会更新零值
	// 由于role的0表示管理员，所以使用map更新数据
	var maps = make(map[string]interface{})
	maps["title"] = article.Title
	maps["desc"] = article.Desc
	maps["context"] = article.Context
	maps["cid"] = article.Cid
	maps["img"] = article.Img
	err := db.Model(&Article{}).Where("id = ?", id).Update(maps).Error
	if err != nil {
		return msg.ERROR_USER_EDIT
	}
	return msg.SUCCESS
}
